<template>
	<view class="content">
		<!--此方法只需要在wxml里添加下面代码即可，无需用 bindtap关联函数-->
		<view class="top">
			<view class="text">
				<h1 class="title">蓝牙自动开关配置</h1>
				<text class="title-en">Automated configuration</text>
				<image src="@/static/images/juxing.png" />
			</view>

			<image src="@/static/images/chahua.png" class="position-img" />
		</view>
		<view class="scancode-box">
			<view class="scancode">
				<h2 class="scancodetitle">STEP 01：扫码获取产品信息</h2>
				<view class="scan-input">
					<input class="uni-input" :value="scanValue" placeholder="暂无产品信息" disabled />
					<uni-icons class="scan-icon" type="scan" @click="handleScan"></uni-icons>
				</view>
			</view>
		</view>
		<view class="time-box">
			<view class="setting-box">
				<h2 class="time-title">STEP 01：扫码获取产品信息</h2>
				<view class="setting-time">
					<uni-forms ref="valiForm" :rules="rules" :modelValue="timeFormData">
						<uni-forms-item label="通电时间:" name="name">
							<picker mode="time" :value="timeFormData.powerOnTime" @change="powerOnTimeChange">
								<view class="uni-input">{{timeFormData.powerOnTime}}</view>
							</picker>
						</uni-forms-item>
						<uni-forms-item label="断电时间:" name="age">
							<picker mode="time" :value="timeFormData.powerOutageTime" @change="powerOutageTimeChange">
								<view class="uni-input">{{timeFormData.powerOutageTime}}</view>
							</picker>
						</uni-forms-item>

					</uni-forms>
					<view class="submit-btn" @click="submit(timeFormData)">
						<image v-if="ishow" src="@/static/images/time.png" />
						<image v-else src="@/static/images/time2.png" />
					</view>
				</view>
			</view>
		</view>
		<view class="history-box">
			<view class="setting-history">
				<view class="history-title">
					<view class="min-title">
						历史配置
					</view>
					<view class="click">
						点击选择
					</view>
				</view>
				<view class="history-list" v-if="historyList.length>0">
					<ul>
						<li v-for="(item,index) in historyList" :key="index" @click="changeHistoryTime(item)">
							<span class="sort">0{{index+1}}</span>
							<view class="bluetooth-item">
								<image src="@/static/images/bluetooth.png" mode=""></image>
								<text>通电时间：{{item.powerOnTime}} | 断电时间：{{item.powerOutageTime}}</text>
							</view>
						</li>
					</ul>
				</view>
				<view class="empty" v-else>
					<image src="@/static/images/empty.png" mode=""></image>
				</view>
			</view>
		</view>

		<uni-popup ref="alertDialog">
			<view class="popup-content">
				<img class="img" src="@/static/images/confirm-img.png" alt="">
				<text class="text">蓝牙配置</text>
				<text class="text">设置成功</text>
				<view class="confirm-btn" @click="confirmBtn">
					确认
				</view>
			</view>
		</uni-popup>
		<uni-popup ref="alertIOS" :mask-click="false">
			<view class="popup-content">
				<view class="title">
					错误
				</view>
				<text class="text">IOS系统因底层原因暂无法使用，请使用其它手机</text>
				<view class="confirm-btn" @click="handleExit">
					确认
				</view>
			</view>
		</uni-popup>
	</view>
</template>

<script>
	import {
		queryConfig,
		addConfig
	} from '@/api/index.js'
	import {
		ab2hex,
		hexCharCodeToStr,
		stringTobuffer,
		decimalToHex,
		arrTobuffer,
		dateToHex,
		timeToHex,
		calcCheckSum,
		stringToHex,
		ab2str
	} from '@/utils/index.js'
	export default {
		data() {
			return {
				scanValue: "", //码值
				msgType: "",
				timeFormData: {
					powerOnTime: "07:00",
					powerOutageTime: "19:00"
				},
				historyList: [],
				setTime: {
					powerOnTime: "07:00",
					powerOutageTime: "19:00"
				},
				resdic: [], //外部设备
				deviceIdStr: "", //获取的deviceId
				serviceIdStr: "", //获取的serviceId

				Slave: '',
				QRcodeImg: '',
				server: null, //建立本地服务端返回的对象
				value: '', //写的数据
				timerOne: null,
				timerOneNum: 1,
				timerTwo: null,
				timerTwoNum: 1,
				buff: [], //广播数据
				qrcode: [],
				discoveryStarted: false,
				broadcastLock:false,//设置时间锁
			}
		},
		async onLoad() {},
		computed: {
			ishow() {
				return this.timerTwoNum == '1'
			}
		},
		async mounted() {
			if(uni.getSystemInfoSync().platform == 'ios'){
				this.$refs.alertIOS.open()
				return
				// uni.showToast({
				// 	icon: "none",
				// 	title: "不支持iOS",
				// 	duration: 3000,
				// })
			}
			clearInterval(this.timerOne)
			clearInterval(this.timerTwo)
			queryConfig({
				// "serialNumber": this.scanValue
			}).then(res => {
				// console.log(res.data)
				this.historyList = res.data.reverse().slice(0,5)
			})
			await this.openBluetoothAdapter();
			/* wx.onBLECharacteristicValueChange(res => {
				console.log(111111111111111)
				console.log(`characteristic ${res.characteristicId} has changed, now is ${res.value}`)
				console.log(ab2hex(res.value))
			}) */
		},
		onHide() {

			// this.stopAdvertising()
		},
		methods: {
			//退出小程序
			handleExit(){
				console.log(111111111111111111)
				uni.exitMiniProgram({
					success: function() {
						console.log('退出小程序成功');
					},
					fail: function(err) {
						console.log('退出小程序失败', err);
					}
				})
			},
			powerOnTimeChange: function(e) {
				this.timeFormData.powerOnTime = e.detail.value
			},
			powerOutageTimeChange: function(e) {
				this.timeFormData.powerOutageTime = e.detail.value
			},
			dialogToggle(type) {
				this.msgType = type
				this.$refs.alertDialog.open()
			},
			confirmBtn() {
				this.$refs.alertDialog.close()

				queryConfig({
					// "serialNumber": this.scanValue
				}).then(res => {
					// console.log(res.data)
					this.historyList = res.data.reverse().slice(0,5)
				})
			},

			//选择历史列表时间
			changeHistoryTime(item) {
				this.timeFormData.powerOnTime = item.powerOnTime
				this.timeFormData.powerOutageTime = item.powerOutageTime
			},
			//扫码获取值
			handleScan() {
				// 允许从相机和相册扫码
				uni.scanCode({
					success: async (res) => {
						// console.log('条码类型：' + res.scanType+'条码内容：' + res.result);
						this.scanValue = res.result
						this.qrcode = stringToHex(this.scanValue)
						
						await this.createBLE();
					}
				});
			},
			//设置时间
			async submit(item) {
				if (!this.scanValue) {
					uni.showToast({
						icon: "none",
						title: "请先扫描产品设备码",
						duration: 3000,
					})
					return
				}
				this.broadcastLock=true
				this.setTime.powerOnTime = item.powerOnTime
				this.setTime.powerOutageTime = item.powerOutageTime
				if (this.timerTwo) {
					clearInterval(this.timerTwo)
				}
				this.timerTwo = setInterval(() => {

					this.setTimeDevice();
				}, 200)

			},
			async submitSuccess() {
				if(!this.broadcastLock){
					return
				}
				this.broadcastLock=false
				this.dialogToggle('info')
				const res = await addConfig({
					serialNumber: this.scanValue,
					powerOnTime: this.setTime.powerOnTime,
					powerOutageTime: this.setTime.powerOutageTime
				})
				// wx.stopBluetoothDevicesDiscovery()
			},
			//蓝牙初始化
			openBluetoothAdapter() {
				uni.openBluetoothAdapter({
					// mode: 'peripheral',
					success: async e => {
						console.log('蓝牙初始化');
						// await this.createBLE();
						this.startBluetoothDevicesDiscovery()
					},
					fail: e => {
						if (e.errCode == 10001) {
							uni.showModal({
								title: "提示",
								content: "您的蓝牙没有打开，请打开蓝牙",
								success: function(res) {
									if (res.confirm == true) {
										if (uni.getSystemInfoSync().platform == 'ios') {} else if (
											uni.getSystemInfoSync().platform ===
											'android') {}
									} else {
										// uni.navigateBack({
										// 	url: '../../detail3/detail3'
										// })
									}
								},
							});
						}
						throw '初始化蓝牙失败，错误码：'
						console.log('初始化蓝牙失败，错误码：' + (e.errCode || e.errMsg));
					}
				});
			},
			startBluetoothDevicesDiscovery() {
				if (this.discoveryStarted) {
					return
				}
				this.discoveryStarted = true
				wx.startBluetoothDevicesDiscovery({
					allowDuplicatesKey: true,
					powerLevel: "high",
					success: res => {
						this.onBluetoothDeviceFound()
					},
					fail: res => {
						onsole.log("查找设备失败!");
					}
				})
			},
			inArray(arr, key, val) {
				for (let i = 0; i < arr.length; i++) {
					if (arr[i][key] === val) {
						return i;
					}
				}
				return -1;
			},
			onBluetoothDeviceFound() {
				wx.onBluetoothDeviceFound((res) => {
					res.devices.forEach(device => {
						if (!device.name && !device.localName) {
							return
						}
						var bytes = Array.prototype.map.call(new Uint8Array(device.advertisData), bit => (
							'00' + bit.toString(16)).slice(-2)).join('');

						if (this.qrcode) {
							var qecodebytes = "ff550d00" + Array.prototype.map.call(new Uint8Array(this
								.qrcode), bit => (
								'00' + bit.toString(16)).slice(-2)).join('');
							// console.log('this.qrcode', qecodebytes)
						}
						// console.log(device,'device')
						if (bytes.indexOf(qecodebytes) > '-1') {
							// console.log(bytes, device, '@@')
							// console.log(bytes, device, '@@')
							// wx.stopBluetoothDevicesDiscovery()
							this.submitSuccess()
						}
					})
				})
			},

			// 创建从机服务端
			createBLE() {
				let _this = this
				wx.createBLEPeripheralServer({
					success: (res) => {
						_this.Slave = "成功"
						_this.server = res.server
						if (res.errMsg == "createBLEPeripheralServer:ok") {
							// wx.showToast({
							// 	title: '创建成功',
							// 	icon: 'success'
							// })

							//初始化设置时间同步广播
							if (_this.timerOne) {
								clearInterval(_this.timerOne)
							}
							_this.timerOne = setInterval(() => {

								_this.timeSynchronizationDevice(); //开启广播
							}, 200)
						}
						res.server.addService({
							service: {
								uuid: "000018f0-0000-1000-8000-00805f9b34fb",
								characteristics: [{
										uuid: "00002af0-0000-1000-8000-00805f9b34fb",
										properties: {
											read: true,
											notify: true
										},
										permission: {
											readable: true
										},
										// value: _this.string2buffer("123"),
									},
									{
										uuid: "00002af1-0000-1000-8000-00805f9b34fb",
										properties: {
											writeNoResponse: true,
											extendedProperties: true
										},
										permission: {
											writeable: true
										},
										// value: _this.string2buffer("321"),
									}
								]
							},
							success(res) {
								console.log('添加服务成功:', res);
								_this.setOnRequest(); //监听读写操作
								// _this.startAdvertising(); //开启广播
							},
							fail(err) {
								console.log('添加服务失败:', err)
								_this.createBLE()
							}
						});

					}
				})
			},
			//设置时间同步
			timeSynchronizationDevice() {
				// this.startBluetoothDevicesDiscovery()
				if (this.timerOne && this.timerOneNum == 10) {
					clearInterval(this.timerOne)
					this.stopAdvertising()
					this.$set(this, 'timerOneNum', '1')
					return
				} else {
					this.timerOneNum++;
				}
				// let qrcode = ["0x58", "0x48", "0x44", "0x31","0x32", "0x33", "0x34","0x35", "0x36", "0x37", "0x38", "0x39"]
				let time = dateToHex(new Date())
				let check = calcCheckSum(["0x10", "0x01", ...this.qrcode, ...time])
				this.buff = [0xFF, 0x55, 0x10, 0x01, ...this.qrcode, ...time, '0x' + check];
				// this.buff = buff.map(item => parseInt(item))
				this.startAdvertising({
					title: "已开启时间同步广播"
				})
			},
			//设置时间开关机
			setTimeDevice() {
				// this.startBluetoothDevicesDiscovery()
				if (this.timerTwo && this.timerTwoNum == 10) {
					clearInterval(this.timerTwo)
					this.stopAdvertising()
					this.$set(this, 'timerTwoNum', '1')
					return
				} else {
					console.log(this.timerTwoNum, 'this.timerTwoNum')
					this.timerTwoNum++
				}
				// let qrcode = ["0x58", "0x48", "0x44","0x31", "0x32", "0x30","0x33", "0x30", "0x31","0x32", "0x33", "0x34","0x35", "0x35"]
				let timeStart = timeToHex(this.setTime.powerOnTime)
				let timeEnd = timeToHex(this.setTime.powerOutageTime)
				let check = calcCheckSum(["0x11", "0x00", ...this.qrcode, ...timeStart, ...timeEnd])
				this.buff = [0xFF, 0x55, 0x11, 0x00, ...this.qrcode, ...timeStart, ...timeEnd, '0x' + check];
				// let buff = [0x0a, 0x0b, 0x0c, 0x0d];
				this.startAdvertising({
					title: "已开启时间设置广播"
				})
			},

			setOnRequest() {
				var that = this;
				console.log("设置监听读写");
				if (that.server) {
					that.server.onCharacteristicWriteRequest(function callback(res) {
						console.log('写入请求监听')
						console.log("写入的数据:" + that.buf2string(res.value))
						that.value = that.buf2string(res.value)
						that.server.writeCharacteristicValue({
							serviceId: res.serviceId,
							characteristicId: res.characteristicId,
							value: res.value,
							needNotify: true,
							callbackId: res.callbackId
						})
					})
					that.server.onCharacteristicReadRequest(function callback(res) {
						console.log('读取请求监听')
						that.server.writeCharacteristicValue({
							serviceId: res.serviceId,
							characteristicId: res.characteristicId,
							// value: that.string2buffer("5555"),
							needNotify: true,
							callbackId: res.callbackId
						})
					})
				}
			},
			buf2string(buffer) {
				var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
				var str = ''
				for (var i = 0; i < arr.length; i++) {
					str += String.fromCharCode(arr[i])
				}
				return str
			},
			/* string2buffer(str) {
				// 首先将字符串转为16进制
				let val = ""
				for (let i = 0; i < str.length; i++) {
					if (val === '') {
						val = str.charCodeAt(i).toString(16)
					} else {
						val += ',' + str.charCodeAt(i).toString(16)
					}
				}
				// 将16进制转化为ArrayBuffer
				return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function(h) {
					return parseInt(h, 16)
				})).buffer
			}, */
			startAdvertising(params) {
				// console.log('checkcheck', this.buff,new Date().getSeconds().toString(16).padStart(2, '0'))
				this.server.startAdvertising({
					advertiseRequest: {
						deviceName: "",
						// serviceUuids: ["000018f0-0000-1000-8000-00805f9b34fb"],
						manufacturerData: [{
							manufacturerId: 0x01AC,
							manufacturerSpecificData: this.buff
						}]
					},
					powerLevel: 'high',
					success: res => {
						if (res.errMsg == "startBLEPeripheralAdvertising:ok") {
							
							console.log('startBLEPeripheralAdvertising', this.buff, new Date().getSeconds()
								.toString(16).padStart(2, '0'))
							// wx.showToast({
							// 	title: params.title || "已开启广播",
							// 	icon: 'success'
							// })
						}

					},

					fail: error => {
						console.log("startAdvertising fail:" + JSON.stringify(error));
					}
				});
			},
			// 停止广播
			stopAdvertising() {
				console.log("停止广播");
				this.server.stopAdvertising({
					success: (res) => {
						// this.timerOneNum = 1
						// this.timerTwoNum = 1
						console.log(this.timerTwoNum, 'this.stopAdvertising')
						// console.log(res);
						// wx.showToast({
						// 	title: '广播已停止',
						// 	icon: 'success'
						// })
					}
				})
			}


		}
	}
</script>

<style lang="less" scoped>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.top {
		width: 100%;
		height: 382rpx;
		background: url('../../static/images/beijingse.png') center bottom no-repeat;
		background-size: cover;
		position: relative;

		.text {
			margin-left: 60rpx;

			.title {
				font-size: 40rpx;
				line-height: 52rpx;
				color: rgb(253, 253, 254);
				font-weight: 700;
				display: block;
				margin-top: 112rpx;
				margin-bottom: 6rpx;
			}

			.title-en {
				font-size: 18rpx;
				line-height: 24rpx;
				color: rgb(253, 253, 254);
				opacity: 0.3;
				display: block;
				margin-bottom: 40rpx;
			}

			image {
				width: 48rpx;
				height: 12rpx;
			}
		}

		.position-img {
			position: absolute;
			top: 70%;
			transform: translateY(-50%);
			right: 60rpx;
			width: 282rpx;
			height: 270rpx;
		}
	}

	.scancode-box {
		position: relative;
		z-index: 2;
		width: calc(100% - 60rpx);
		margin: -94rpx auto 0;

		.scancode {
			position: relative;
			padding: 32rpx;
			border-radius: 20rpx;
			background: rgba(253, 253, 254, 0.5);
			box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
			backdrop-filter: blur(36rpx);
			border: 1rpx solid rgb(234, 234, 234);

			.scancodetitle {
				font-weight: 700;
				font-size: 32rpx;
				line-height: 46rpx;
				margin-bottom: 32rpx;
				color: #333333;
			}

			.scan-input {
				display: flex;
				justify-content: space-between;
				align-items: center;

				.uni-input {
					width: 498rpx;
					height: 88rpx;
					border-radius: 12rpx;
					background-color: rgb(253, 253, 254);
					border: 1px solid rgb(234, 234, 234);
					line-height: 38rpx;
					font-size: 26rpx;
					padding: 0 0 0 32rpx;

					:-moz-placeholder {
						font-size: 26rpx;
						line-height: 38rpx;
						color: #999999;
					}
				}

				/deep/.scan-icon {
					.uniui-scan {
						font-size: 80rpx !important;
					}
				}
			}
		}
	}

	.time-box {
		margin-top: 32rpx;
		width: calc(100% - 60rpx);

		.setting-box {
			position: relative;
			padding: 32rpx;
			border-radius: 20rpx;
			background: rgba(253, 253, 254, 0.5);
			box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05);
			border: 1rpx solid rgb(234, 234, 234);

			.time-title {
				font-weight: 700;
				font-size: 32rpx;
				line-height: 46rpx;
				margin-bottom: 32rpx;
				color: #333333;
			}

			.setting-time {
				display: flex;
				justify-content: space-between;

				/deep/.uni-forms {
					flex: 0 0 calc(100% - 192rpx);
					width: calc(100% - 192rpx);

					.uni-forms-item {
						align-items: center;
						margin-bottom: 20rpx;

						&:last-child {
							margin-bottom: 0;
						}
					}

					.uni-forms-item__label {
						width: 140rpx !important;
						font-size: 26rpx;
					}

					.uni-forms-item__content {
						background-color: rgb(238, 238, 238);
						width: 292rpx;
						height: 88rpx;
						line-height: 88rpx;
						border-radius: 6px;
						text-align: center;
					}
				}

				.submit-btn {
					width: 172rpx;
					flex: 0 0 172rpx;
					height: 196rpx;
					border-radius: 12rpx;

					image {
						width: 100%;
						height: 100%;
					}
				}
			}
		}
	}

	.history-box {

		margin: 32rpx 0;
		width: calc(100% - 60rpx);

		.setting-history {
			padding: 32rpx;
			border-radius: 20rpx;
			background: rgb(238, 238, 238);
			border: 1rpx solid rgb(234, 234, 234);
			min-height: 592rpx;

			.history-title {
				display: flex;
				justify-content: space-between;
				margin-bottom: 32rpx;

				.min-title {
					font-weight: 400;
					font-size: 26rpx;
					line-height: 38rpx;
					color: #666666;
				}

				.click {
					color: #999999;
					font-weight: 400;
					font-size: 26rpx;
					line-height: 38rpx;
				}
			}

			.empty {
				height: 520rpx;
				justify-content: center;
				display: flex;
				align-items: center;

				image {
					width: 428rpx;
					height: 300rpx;
				}
			}

			.history-list {
				height: 520rpx;

				ul {
					li {
						display: flex;
						justify-content: space-between;
						height: 88rpx;
						margin-bottom: 20rpx;
						align-items: center;

						&:last-child {
							margin-bottom: 0;
						}

						.sort {
							font-weight: 400;
							font-size: 26rpx;
							line-height: 38rpx;
							color: #666666;
						}

						.bluetooth-item {
							background-color: rgb(253, 253, 254);
							padding: 24rpx 28rpx;
							flex: 0 0 500rpx;
							width: 500rpx;
							border-radius: 12rpx;
							border: 2rpx solid rgb(234, 234, 234);
							display: flex;
							align-items: center;
							justify-content: space-between;

							text {
								font-weight: 400;
								font-size: 26rpx;
								line-height: 38rpx;
								color: #666666;
							}

							image {
								width: 40rpx;
								height: 40rpx;
							}
						}
					}
				}
			}
		}
	}

	.popup-content {
		background-color: #fff;
		width: 556rpx;
		height: 368rpx;
		border-radius: 20rpx;
		text-align: center;
		position: relative;
		display: flex;
		align-items: center;
		justify-content: center;
		flex-direction: column;

		.img {
			position: absolute;
			left: 50%;
			transform: translateX(-50%);
			top: -115rpx;
			width: 282rpx;
			height: 270rpx;
		}

		.text {
			font-weight: 700;
			font-size: 30rpx;
			line-height: 44rpx;
			color: #333333;
		}

		.confirm-btn {
			position: absolute;
			width: 100%;
			left: 0%;
			bottom: 0;
			background-color: rgb(48, 92, 255);
			color: #fff;
			font-weight: 700;
			font-size: 30rpx;
			line-height: 44rpx;
			padding: 24rpx 0 22rpx 0;
			border-radius: 0 0 20rpx 20rpx;
		}
		.title{
			position: absolute;
			font-weight: 700;
			width: 100%;
			left: 0%;
			top: 30rpx;
			font-size: 40rpx;
			line-height: 55rpx;
			text-align: center;
		}
	}
</style>